package club.xyes.zkh.ecommerce.web.api.controller;

import club.xyes.zkh.ecommerce.commons.entity.Commodity;
import club.xyes.zkh.ecommerce.commons.entity.CommodityClassification;
import club.xyes.zkh.ecommerce.commons.entity.Shop;
import club.xyes.zkh.ecommerce.commons.exception.BadRequestException;
import club.xyes.zkh.ecommerce.commons.properties.WebsiteConfigurationProperties;
import club.xyes.zkh.ecommerce.commons.util.EntityImagePathUtils;
import club.xyes.zkh.ecommerce.commons.util.TextUtil;
import club.xyes.zkh.ecommerce.commons.vo.GeneralResult;
import club.xyes.zkh.ecommerce.service.CommodityClassificationService;
import club.xyes.zkh.ecommerce.service.CommodityImageService;
import club.xyes.zkh.ecommerce.service.CommodityService;
import club.xyes.zkh.ecommerce.service.ShopService;
import club.xyes.zkh.ecommerce.web.controller.BaseController;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.Objects;

/**
 * Create by 郭文梁 2019/4/17 0017 10:27
 * CommodityController
 * 商品相关数据访问控制器
 *
 * @author 郭文梁
 * @data 2019/4/17 0017
 */
@RestController
@RequestMapping("/api/commodity")
@Api("商品相关API接口")
public class CommodityController extends BaseController<Commodity> {
    private static final int DEFAULT_PAGE = 1;
    private static final int DEFAULT_ROWS = 10;
    private final CommodityService service;
    private final ShopService shopService;
    private final CommodityClassificationService commodityClassificationService;
    private final CommodityImageService commodityImageService;
    private final WebsiteConfigurationProperties websiteConfigurationProperties;

    @Autowired
    public CommodityController(CommodityService service,
                               ShopService shopService,
                               CommodityClassificationService commodityClassificationService,
                               CommodityImageService commodityImageService,
                               WebsiteConfigurationProperties websiteConfigurationProperties) {
        super(service);
        this.service = service;
        this.shopService = shopService;
        this.commodityClassificationService = commodityClassificationService;
        this.commodityImageService = commodityImageService;
        this.websiteConfigurationProperties = websiteConfigurationProperties;
    }

    /**
     * 查询某分类下的商品
     *
     * @param classificationId 分类ID
     * @param page             页码
     * @param rows             每页大小
     * @return 商品列表
     */
    @GetMapping("/classification/{classificationId}")
    @ApiOperation("根据分类查询商品")
    public GeneralResult<PageInfo<Commodity>> byClassificationId(@PathVariable("classificationId") Integer classificationId,
                                                                 Integer page,
                                                                 Integer rows) {
        page = page == null ? DEFAULT_PAGE : page;
        rows = rows == null ? DEFAULT_ROWS : rows;
        PageInfo<Commodity> commodities = service.findByClassificationId(classificationId, page, rows);
        List<Commodity> commodityList = EntityImagePathUtils.prettyCommodityFrontCoverPath(commodities.getList(),
                websiteConfigurationProperties.getStaticServerPrefix(),
                websiteConfigurationProperties.getCommodityFrontCoverPath());
        commodities.setList(commodityList);
        return GeneralResult.ok(commodities);
    }

    /**
     * 创建信息商品信息
     *
     * @param classificationId 分类ID
     * @param commodity        商品(name, description, recommend)
     * @param frontCoverFile   商品封面图片
     * @return GR
     * @throws IOException IO异常
     */
    @ApiOperation("创建指定分类的商品信息")
    @PostMapping("/classification/{classificationId}")
    public GeneralResult<Commodity> create(@PathVariable("classificationId") Integer classificationId,
                                           Commodity commodity,
                                           MultipartFile frontCoverFile) throws IOException {
        if (frontCoverFile == null || frontCoverFile.isEmpty()) {
            return GeneralResult.badRequest("未上传文件");
        }
        if (commodity == null
                || TextUtil.isTrimedEmpty(commodity.getName())
                || commodity.getRecommend() == null) {
            return GeneralResult.badRequest("缺少参数");
        }
        CommodityClassification classification = commodityClassificationService.getRequired(classificationId);
        Shop shop = currentShop();
        if (!Objects.equals(shop.getId(), classification.getShopId())) {
            return GeneralResult.badRequest("您无权操作该数据");
        }
        Commodity target = new Commodity();
        target.setClassificationId(classificationId);
        target.setName(commodity.getName());
        target.setDescription(commodity.getDescription());
        target.setRecommend(commodity.getRecommend());
        target.setPrice(commodity.getPrice());
        target.setState(Commodity.STATE_ENABLE);
        Commodity res = service.create(target, frontCoverFile);
        EntityImagePathUtils.prettyCommodityFrontCoverPath(res,
                websiteConfigurationProperties.getStaticServerPrefix(),
                websiteConfigurationProperties.getCommodityFrontCoverPath());
        return GeneralResult.ok(res);
    }

    /**
     * 更新商品信息
     *
     * @param id        商品ID
     * @param commodity 商品数据{name description recommend, classificationId}
     * @return GR
     */
    @ApiOperation("更新商品信息")
    @PostMapping("/{id}")
    public GeneralResult<Commodity> update(@PathVariable Integer id,
                                           @RequestBody Commodity commodity) {
        Commodity target = service.getRequired(id);
        checkPermission(target, commodity.getClassificationId());

        target.setName(commodity.getName());
        target.setDescription(commodity.getDescription());
        target.setRecommend(commodity.getRecommend());
        target.setClassificationId(commodity.getClassificationId());
        target.setPrice(commodity.getPrice());
        Commodity res = service.updateById(target);
        EntityImagePathUtils.prettyCommodityFrontCoverPath(res,
                websiteConfigurationProperties.getStaticServerPrefix(),
                websiteConfigurationProperties.getCommodityFrontCoverPath());
        return GeneralResult.ok(res);
    }

    /**
     * 检查商铺操作权限
     *
     * @param commodity        商铺对象
     * @param classificationId 将要修改到的目标分类
     */
    private void checkPermission(Commodity commodity, Integer classificationId) {
        Shop shop = currentShop();
        CommodityClassification sourceClass = commodityClassificationService.getRequired(commodity.getClassificationId());
        if (!Objects.equals(sourceClass.getShopId(), shop.getId())) {
            throw new BadRequestException("您无权操作该数据");
        }
        if (!Objects.equals(classificationId, commodity.getClassificationId())) {
            CommodityClassification targetClass = commodityClassificationService.getRequired(classificationId);
            if (!Objects.equals(targetClass.getShopId(), shop.getId())) {
                throw new BadRequestException("该分类不属于您的商铺");
            }
        }
    }

    /**
     * 设置商品封面
     *
     * @param id        商品ID
     * @param coverFile 封面文件
     * @return GR
     * @throws IOException IO异常
     */
    @PostMapping("/{id}/_set-cover")
    @ApiOperation("设置商品封面")
    public GeneralResult<Commodity> setCover(@PathVariable("id") Integer id,
                                             MultipartFile coverFile) throws IOException {
        if (coverFile == null || coverFile.isEmpty()) {
            return GeneralResult.badRequest("未上传文件");
        }
        Commodity commodity = service.getRequired(id);
        checkPermission(commodity, commodity.getClassificationId());
        Commodity res = service.setFrontCover(commodity, coverFile);
        EntityImagePathUtils.prettyCommodityFrontCoverPath(res,
                websiteConfigurationProperties.getStaticServerPrefix(),
                websiteConfigurationProperties.getCommodityFrontCoverPath());
        return GeneralResult.ok(res);
    }

    /**
     * 删除商品
     *
     * @param id 商品ID
     * @return GR
     */
    @DeleteMapping("/{id}")
    @ApiOperation("删除商品")
    public GeneralResult<Commodity> delete(@PathVariable("id") Integer id) {
        Commodity commodity = service.getRequired(id);
        checkPermission(commodity, commodity.getClassificationId());
        if (commodityImageService.existsByCommodityId(id)) {
            commodityImageService.deleteByCommodityId(id);
        }
        EntityImagePathUtils.prettyCommodityFrontCoverPath(commodity,
                websiteConfigurationProperties.getStaticServerPrefix(),
                websiteConfigurationProperties.getCommodityFrontCoverPath());
        if (service.deleteById(commodity.getId())) {
            return GeneralResult.ok(commodity);
        } else {
            return GeneralResult.error("Unable to delete Commodity for id " + id);
        }
    }

    /**
     * 根据商铺查找商品
     *
     * @param shopId 商铺ID
     * @param page   页码
     * @param rows   每页大小
     * @return GR
     */
    @ApiOperation("查询商铺的商品")
    @GetMapping("/shop/{shopId}")
    public GeneralResult<PageInfo<Commodity>> findByShop(@PathVariable("shopId") Integer shopId,
                                                         Integer page, Integer rows) {
        page = page == null ? DEFAULT_PAGE : page;
        rows = rows == null ? DEFAULT_ROWS : rows;
        Shop shop = shopService.getRequired(shopId);
        PageInfo<Commodity> commodityPageInfo = service.findByShop(shop, page, rows);
        return GeneralResult.ok(commodityPageInfo);
    }

    /**
     * 通过商铺ID和商品名称搜索商品
     *
     * @param name  商铺名称 模糊匹配
     * @param page  页码
     * @param rows  每页大小
     * @param state 状态
     * @return GR
     */
    @ApiOperation("搜索商家的商品")
    @GetMapping("/shop/search")
    public GeneralResult<PageInfo<Commodity>> search(@RequestParam("name") String name,
                                                     @RequestParam("state") Integer state,
                                                     Integer page, Integer rows) {

        page = page == null ? DEFAULT_PAGE : page;
        rows = rows == null ? DEFAULT_ROWS : rows;
        String server = websiteConfigurationProperties.getStaticServerPrefix();
        String frontCoverPath = websiteConfigurationProperties.getCommodityFrontCoverPath();
        PageInfo<Commodity> res = service.searchByShopIdAndStateAndName(currentShop().getId(), state, name, page, rows);
        res.setList(EntityImagePathUtils.prettyCommodityFrontCoverPath(res.getList(), server, frontCoverPath));
        return GeneralResult.ok(res);
    }

    /**
     * 商品上下架操作
     *
     * @param id    上牌ID
     * @param param {state:1}
     * @return GR
     */
    @ApiOperation("商品上下架操作")
    @PostMapping("/{id}/operate")
    public GeneralResult<Commodity> operate(@PathVariable("id") Integer id,
                                            @RequestBody Commodity param) {
        if (param == null || param.getState() == null) {
            return GeneralResult.badRequest("缺少参数");
        }
        Commodity commodity = service.getRequired(id);
        commodity.setState(param.getState());
        Commodity res = service.updateById(commodity);
        return GeneralResult.ok(res);
    }

    /**
     * 当前商铺
     *
     * @return 商铺
     */
    private Shop currentShop() {
        return currentShop(shopService);
    }
}
